#lang racket


(require "../base/base.rkt")

(require "domain.rkt"
         "curve.rkt")


(provide (struct-out helix-curve)
         make-helix-curve)


(define-struct (helix-curve curve)
  (ax ay az)
  #:constructor-name new-helix-curve)

(define (helix-curve-object ax ay az)
  (λ (t)
    (xyz
     (* ax (cos t))
     (* ay (sin t))
     (* az t))))

(define (helix-curve-tangent ax ay az)
  (λ (t)
    (xyz
     (- (* ax (sin t)))
     (* ay (cos t))
     az)))

(define (helix-curve-normal ax ay az)
  (λ (t)
    (xyz
     (- (* ax (+ (* ax ay) (^2 az)) (cos t)))
     (- (* ay (+ (* ax ay) (^2 az)) (sin t)))
     0)))

(define (helix-curve-binormal ax ay az)
  (λ (t)
    (xyz
     (* ax az (sin t))
     (- (* ay az (cos t)))
     (* ax ay))))

(define (make-helix-curve ax ay az)
  (new-helix-curve
   (make-domain 'closed 0 'open 2pi)
   (helix-curve-object ax ay az)
   (helix-curve-tangent ax ay az)
   (helix-curve-normal ax ay az)
   (helix-curve-binormal ax ay az)
   ax
   ay
   az))